//
//  QKS.swift
//  TransQuick
//
//  Created by licc on 2020/5/21.
//  Copyright © 2020 licc. All rights reserved.
//

import Foundation
import UIKit
//import UIKit

//协议 QKP
public protocol QKP {
    associatedtype TT
    
    var quick: TT { get }
}

public extension QKP {
    var quick: QKC<Self,Void,QKC<Self,Void,Void,Void>,Void > {
        return QKC.init(value: self,master: (), root:QKC.init(value: self,master: (),root:(),next: ()),next: ())
    }
}

// 所有继承于NSObject的类增加协议 QKP
extension NSObject: QKP{}
extension UIEdgeInsets: QKP{}

@available(iOS 11.0, *)
extension NSDirectionalEdgeInsets: QKP {}

extension CGPoint: QKP {}
extension CGRect: QKP {}
extension CGSize: QKP {}
extension CGVector: QKP {}
extension Array: QKP {}
extension Dictionary: QKP {}
extension Set: QKP {}
extension UIInterfaceOrientation: QKP {}

extension UIFloatRange: QKP {}
extension UIContentSizeCategory: QKP {}
extension UIDeviceOrientation: QKP {}
//extension UITextDirection: QKP {}
//extension UIAccessibility: QKP {}


//extension UIContentSizeCategory: QKP {}
//extension UIContentSizeCategory: QKP {}
//extension UIContentSizeCategory: QKP {}
//extension UIContentSizeCategory: QKP {}




extension UIOffset: QKP {}
//运算符
precedencegroup QKPrecedence {
    associativity: left             //左结合
//    lowerThan: AdditionPrecedence   // 优先级低于加法运算符
    lowerThan: LogicalConjunctionPrecedence   // 优先级低于?运算符

}
/// QKC 增加一个 节点 节点头不动
infix operator +^:QKPrecedence
/// QKC 移动节点头到前一个节点
postfix operator <^
/// QKC 移动节点头到下一个节点
postfix operator >^
/// QKC 移动节点头到根节点
postfix operator <<<^
/// 节点不动
postfix operator =^

/// QKC 链条容器类
///泛型 AA,YY,ZZ,CC 分别代表
///AA：当前value的类型
///YY: 前一个链条的QKC类型
///ZZ: 根链条的QKC类型
///CC:下一个数值的实际类型
public class QKC<AA,YY,ZZ,CC> {
    public var value: AA             ///实际存储的值
    public var master: YY           ///上一个链条容器，支持一直上溯到根链条
    public var root: ZZ        ///根链条 本组链条的头/根 容器
    public var nextValue:CC         ///下一个值
    public var next: QKC<CC,QKC<AA,YY,ZZ,CC>,ZZ,Void>    ///下一个链条
    { get{ return QKC<CC,QKC<AA,YY,ZZ,CC>,ZZ,Void>.init(value: nextValue, master: self, root: root, next: ())}}
    
    public init(value: AA,master: YY ,root:ZZ,next:CC)  {
        self.value = value
        self.master = master
        self.root = root
        self.nextValue = next
    }
    
  /// 连接下一个
  /// - Parameternext: next 下一个元素
  /// - Returns: value 的 QKCC
    @discardableResult
    func link<MM>(next:MM ) -> QKC<AA,YY,ZZ,MM>{
        return QKC<AA,YY,ZZ,MM>(value: self.value, master: self.master, root: self.root, next: next)
    }
  
    /// 参考 https://github.com/devxoul/Then
    @discardableResult
    public func then_QK(_ block: (_ self :QKC<AA,YY,ZZ,CC>) throws -> Void) rethrows -> Self {
        try block(self)
        return self
    }
    

    
    /// 返回本身
    public var quick:QKC<AA,YY,ZZ,CC>{
        return self
    }
    ///返回本身 可以在此添加一些注视
    @discardableResult
    public func quick(_ info:String? = nil) -> QKC<AA,YY,ZZ,CC>{
        return self
    }
    
//    ///   - lhs: An optional value to compare.
//    ///   - rhs: Another optional value to compare.
//    static func +^<MM> (lhs:QKC<AA,YY,ZZ,CC> ,rhs:MM ) -> QKC<AA,YY,ZZ,MM>{
//        return lhs.link(next: rhs)
//    }
//    postfix static func <^ (lhs:QKC<AA,YY,ZZ,CC> ) -> YY{
//        return lhs.master
//    }
//
//    postfix static func <<<^ (lhs:QKC<AA,YY,ZZ,CC> ) -> ZZ{
//        return lhs.root
//    }
//
//    postfix static func =^ (lhs:QKC<AA,YY,ZZ,CC> ) -> QKC<AA,YY,ZZ,CC>{
//        return lhs
//    }
//
//     public postfix static func >^ (lhs:QKC<AA,YY,ZZ,CC> ) -> QKC<CC,QKC<AA,YY,ZZ,CC>,ZZ,Void>{
//        return lhs.next
//    }
    
//    open func gggg2() {
////        gggg1(func2: adddd(_:at:) , a: 4, b: 5)
////               print("abcd")
////        gggg3(func2: adddd(_:with:), a: 13, b: 14)
////        gggg3(func2: adddd(2, at: 3, d: 4), a: 2, b: 3, d: 4)
////        gggg1(func2: aeee(_:at:d:f:), a: 2, b: 3, d: 4)
//
////               QKC.adddd(self)(a: 14, with: 15)
//    }
//    open func gggg1<AA,BB,DD,EE>(func2:(AA,BB,DD)->EE ,a:AA,b:BB,d:DD) {
//        func2(a,b,d)
//
//        
//        
//    
//    }
//    open func gggg3 (func2:(Int,Int,Int)->Int ,a:Int,b:Int,d:Int) {
//            func2(a,b,d)
//        }
//
//    open func adddd(_ a:Int ,with  b:Int ) ->Int{
//        print("abc",a,b)
//
//        return a + b
//    }
//    open func adddd(_ a:Int ,at  b:Int ) ->Int{
//        print("abc2",a,b)
//
//        return a + b
//    }
    open func aeee<AA,BB,DD>(_ a:AA ,at  b:BB,d:DD? = nil ,f:Int?=nil) ->Int{
        print("abc2abd",a,b)
        UILabel.init().quick>^.value=()
        return 5
    }
    
}

  ///   - lhs: An optional value to compare.
  ///   - rhs: Another optional value to compare.
public func +^<AA,YY,ZZ,CC,MM> (lhs:QKC<AA,YY,ZZ,CC> ,rhs:MM ) -> QKC<AA,YY,ZZ,MM>{
      return lhs.link(next: rhs)
  }
  public postfix   func <^<AA,YY,ZZ,CC>  (lhs:QKC<AA,YY,ZZ,CC> ) -> YY{
      return lhs.master
  }
  
  public postfix   func <<<^<AA,YY,ZZ,CC>  (lhs:QKC<AA,YY,ZZ,CC> ) -> ZZ{
      return lhs.root
  }

  public postfix   func =^<AA,YY,ZZ,CC>  (lhs:QKC<AA,YY,ZZ,CC> ) -> QKC<AA,YY,ZZ,CC>{
      return lhs
  }

 postfix public  func >^<AA,YY,ZZ,CC>  (lhs:QKC<AA,YY,ZZ,CC> ) -> QKC<CC,QKC<AA,YY,ZZ,CC>,ZZ,Void>{
      return lhs.next
  }
